import logging

from aiogram import Bot
from fluentogram import TranslatorRunner

from src.application.bot_settings.service import BotSettingsService
from src.application.order.enums import OrderType
from src.application.order.service import OrderService
from src.application.user.exceptions import NotEnoughBalance
from src.application.user.service import UserService
from src.infrastructure.date_helpers import format_datetime
from src.infrastructure.utils.helpers import get_expiring_on
from src.presentation.tg_bot.services.locale import Localizator
from src.presentation.tg_bot.services.tg_helpers import broadcast
from src.presentation.tg_bot.worker.exception_handler import exception_handler

logger = logging.getLogger(__name__)


@exception_handler
async def autorenew_orders(ctx) -> None:
    bot: Bot = ctx["bot"]
    fluent: Localizator = ctx["fluent"]
    order_service: OrderService = ctx["order_service"]
    bot_settings_service: BotSettingsService = ctx["bot_settings_service"]
    user_service: UserService = ctx["user_service"]

    bot_settings = await bot_settings_service.get_bot_settings()
    if bot_settings and bot_settings.order_notify_status:
        orders = await order_service.get_expiring_orders(autorenew=True)
        for order in orders:
            logger.info(f"Продлеваю заказ №{order.id}")
            user = await user_service.get_user_by_id(order.buyer_id)

            locale: TranslatorRunner = fluent.get_by_locale(user.lang_code)
            extended_expiring_on = await get_expiring_on(order.expiring_on, order.period)

            error_msg = None
            not_enough_balance_msg = None
            try:
                await order_service.update_order_expiring(order.id, extended_expiring_on)
                logger.info(f"Автоматически продлил заказ №{order.id} до {extended_expiring_on}")
                extended_expiring_on = format_datetime(extended_expiring_on)

                error_msg = locale.get("order-autorenew-error", order_summ=order.summ)
                not_enough_balance_msg = locale.get(
                    "order-autorenew-not-enough-money",
                    order_id=str(order.id),
                    order_summ=order.summ,
                )
                if order.order_type == OrderType.subscription:
                    msg = locale.get(
                        "subscription-autorenew-success",
                        order_summ=order.summ,
                        extended_expiring_on=extended_expiring_on,
                    )
                    not_enough_balance_msg = locale.get(
                        "subscription-autorenew-not-enough-money",
                        order_summ=order.summ,
                    )
                    error_msg = locale.get("subscription-autorenew-error", order_summ=order.summ)
                elif order.order_type == OrderType.vpn:
                    msg = locale.get(
                        "vpn-autorenew-success",
                        order_summ=order.summ,
                        extended_expiring_on=extended_expiring_on,
                    )
                    not_enough_balance_msg = locale.get(
                        "vpn-autorenew-not-enough-money",
                        order_summ=order.summ,
                    )
                    error_msg = locale.get("vpn-autorenew-error", order_summ=order.summ)
                else:
                    msg = locale.get(
                        "order-autorenew-success",
                        order_id=str(order.id),
                        order_summ=order.summ,
                        extended_expiring_on=extended_expiring_on,
                    )
                await broadcast(
                    bot,
                    [user.tg_id],
                    msg,
                )
            except NotEnoughBalance:
                logger.info(f"Недостаточно баланса для продления заказа/подписки №{order.id}")
                if not_enough_balance_msg:
                    await broadcast(
                        bot,
                        [user.tg_id],
                        not_enough_balance_msg,
                    )
            except Exception as e:
                logger.exception(e)
                if error_msg:
                    await broadcast(
                        bot,
                        [user.tg_id],
                        error_msg,
                    )
